package cc.yaomm.service.basic.service.user;

import cc.yaomm.common.basic.enums.PermissionTypeEnum;
import cc.yaomm.common.basic.enums.StatusEnum;
import cc.yaomm.common.basic.util.BeanUtils;
import cc.yaomm.common.basic.util.TokenUtils;
import cc.yaomm.common.biz.enums.SystemEnum;
import cc.yaomm.common.biz.enums.OwnerTypeEnum;
import cc.yaomm.service.basic.entity.user.Permissions;
import cc.yaomm.service.basic.entity.user.Roles;
import cc.yaomm.service.basic.entity.user.Users;
import cc.yaomm.service.basic.manager.LoginManager;
import cc.yaomm.service.basic.manager.PermissionManager;
import cc.yaomm.service.basic.mapper.user.PermissionsMapper;
import cc.yaomm.service.basic.mapper.user.RolesMapper;
import cc.yaomm.service.basic.mapper.user.UsersPermissionsRefMapper;
import cc.yaomm.service.basic.service.user.bo.LoginParamBO;
import cc.yaomm.service.basic.service.user.bo.LoginResultBO;
import cc.yaomm.service.basic.service.user.bo.PermissionResultBO;
import cc.yaomm.service.basic.service.user.vo.RoutesResultVO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class LoginService {

    @Autowired
    private LoginManager loginManager;

    @Autowired
    private PermissionManager permissionManager;

    @Autowired
    private TokenUtils tokenUtils;

    @Autowired
    private RolesMapper rolesMapper;

    @Autowired
    private UsersPermissionsRefMapper usersPermissionsRefMapper;

    @Autowired
    private PermissionsMapper permissionsMapper;

    public LoginResultBO login(LoginParamBO paramBO) {
        //1、验证账号密码
        Users users = loginManager.login(paramBO);
        //构建登录用户信息
        LoginResultBO loginResultBO = new LoginResultBO();
        loginResultBO.setUserId(users.getId());
        loginResultBO.setUserName(users.getName());

        //创建token
        String token = tokenUtils.createToken(users.getId(), JSON.toJSONString(loginResultBO), SystemEnum.BIZ, paramBO.getIp());
        loginResultBO.setToken(token);

        //2、查询用户的角色信息
        List<Roles> rolesList = rolesMapper.findByUserId(OwnerTypeEnum.BIZ, users.getId());
        Assert.isTrue(!CollectionUtils.isEmpty(rolesList), "登录失败，账号没有设置角色");
        //判断用户是否超管
        boolean isAdmin = rolesList.stream().filter(Roles::getIsAdmin).map(Roles::getIsAdmin).findFirst().orElse(false);
        loginResultBO.setIdAdmin(isAdmin);
        List<Permissions> permissionsList;
        if (isAdmin) {
            //4、查询用户的权限信息
            permissionsList = permissionsMapper.findByOwnerType(OwnerTypeEnum.BIZ, StatusEnum.NORMAL);
        } else {
            //3、查询角色关联权限、资源信息
            Set<Long> roleIds = rolesList.stream().map(Roles::getId).collect(Collectors.toSet());
            Set<Long> permissionsIds = usersPermissionsRefMapper.findPermissionsByRoleId(roleIds);
            Assert.isTrue(!CollectionUtils.isEmpty(permissionsIds), "登录失败，账号没有任何权限");
            Set<String> resourcesCodes = usersPermissionsRefMapper.findResourcesByPermissionId(permissionsIds);
            //设置角色访问资源
            loginResultBO.setResources(resourcesCodes);

            //4、查询用户的权限信息
            permissionsList = permissionsMapper.findByIds(permissionsIds);
        }
        Assert.isTrue(!CollectionUtils.isEmpty(permissionsList), "登录失败，账号没有任何权限");

        //5、构造路由（菜单）及按钮权限
        Set<String> permissions = permissionsList.stream()
                .filter(x -> PermissionTypeEnum.BUTTON.equals(x.getType()))
                .filter(x -> StatusEnum.NORMAL.equals(x.getStatus()))
                .map(Permissions::getRouter).collect(Collectors.toSet());
        loginResultBO.setPermissions(permissions);

        //list转tree
        List<PermissionResultBO> resultBOList = permissionManager.convertTree(
                permissionsList.stream()
                        .filter(x -> PermissionTypeEnum.CATALOG.equals(x.getType()) || PermissionTypeEnum.MENU.equals(x.getType()))
                        .filter(x -> StatusEnum.NORMAL.equals(x.getStatus()))
                        .collect(Collectors.toList()));

        List<RoutesResultVO> routers = BeanUtils.mapList(resultBOList, RoutesResultVO.class);

        loginResultBO.setRouters(routers);

        return loginResultBO;
    }


}
